package com.nancy.aop.aop.cglib;

import net.sf.cglib.proxy.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * All rights Reserved, Designed By guangfeng.zhou
 *
 * @version V1.0
 * @Project: learning-demo
 * @Package: com.nancy.aop.cglib
 * @Description: (用一句话描述该文件做什么)
 * @author: guangfeng.zhou
 * @date: 2017/12/5 11:57
 */
public class CglibProxy implements MethodInterceptor {
    private Logger log = LoggerFactory.getLogger(getClass()) ;

    private Enhancer enhancer = new Enhancer();

    public CglibProxy(){
    }

    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        Callback[] callbacks = new Callback[]{ this, NoOp.INSTANCE, new ConcreteClassFixedValue() };
        enhancer.setCallbacks(callbacks);
        /**
         * 返回 index 表示 callbacks数据的位置，调用不同的方法
         * NoOp.INSTANCE ： 直接掉 原始方法 不进行拦截
         * */
        enhancer.setCallbackFilter(new CallbackFilter() {
            public int accept(Method method) {
                if(method.getName().contains("print")){
                    return 0 ;
                }else if("getConcreteMethodFixedValue".equals(method.getName())){
                    return 2 ;
                }
                return 1;
            }
        });
        return enhancer.create() ;
    }

    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        log.info("Transactional begin.. ");
        Object obj = methodProxy.invokeSuper(o, args) ;
        log.info("Transactional end.. ");
        return obj;
    }

    /**
     * 返回固定值
     * @param:
     * @return:
     */
    class ConcreteClassFixedValue implements FixedValue {
        public Object loadObject() throws Exception {
            System.out.println("ConcreteClassFixedValue loadObject ...");
            Object object = 999;
            return object;
        }
    }

}
